package com.icehand.wechat.mini;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Strings;
import com.icehand.common.exception.BaseException;
import com.icehand.wechat.exception.WechatException;
import com.icehand.wechat.utils.AESUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.client.RestTemplate;

/**
 * @author icehand
 */
@Slf4j
@CacheConfig(cacheNames = "wechat-mini")
public class WechatMiniHelper {
    private static final String URL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";

    private final RestTemplate restTemplate;

    public WechatMiniHelper(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @Cacheable(key = "'openid:'+#appId+':'+#uid",condition = "#uid !=null")
    public String getOpneId(String appId, Long uid, String secret, String code){
        WechatMiniSessionResponse wechatMiniSessionResponse = code2Session(appId,secret,code);
        return wechatMiniSessionResponse.getOpenid();
    }

    /**
     * 根据code获取到sessionKey
     * @param appid appid
     * @param secret secret
     * @param code code
     * @return wechatMiniSessionResponse
     */
    public  WechatMiniSessionResponse code2Session(String appid, String secret, String code){
        String str = restTemplate.getForObject(String.format(URL,appid,secret,code),String.class);
        if(Strings.isNullOrEmpty(str)){
            throw new BaseException("code2Session request fail");
        }

        return JSONObject.parseObject(str).toJavaObject(WechatMiniSessionResponse.class);
    }

    /**
     * 解密微信用户数据
     * @param encryptData encryptData
     * @param sessionKey sessionKey
     * @param iv iv
     * @return wechatMiniUserInfo
     */
    public WechatMiniUserInfo decryptUserInfo(String encryptData,String sessionKey,String iv) {
        String str;
        try {
            str = AESUtil.decrypt(encryptData,sessionKey,iv);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("decrypt user info error");
            throw new WechatException("decrypt user info error,data:"+encryptData
                    + "\nsessionKey:"+sessionKey +"\n iv:"+iv);
        }

        if(Strings.isNullOrEmpty(str)){
            throw new WechatException("decrypt user info fail, data:"+encryptData
                    + "\nsessionKey:"+sessionKey +"\n iv:"+iv);
        }

        return JSONObject.parseObject(str).toJavaObject(WechatMiniUserInfo.class);
    }

    /**
     * 解密微信用户数据
     * @param appid appid
     * @param secret secret
     * @param encryptData encryptData
     * @param iv iv
     * @param code code
     * @return wechatMiniUserInfo
     */
    public WechatMiniUserInfo decryptUserInfo(String appid,String secret,String encryptData,String iv,String code){
        WechatMiniSessionResponse sessionResponse = code2Session(appid, secret, code);
        return decryptUserInfo(encryptData,sessionResponse.getSession_key(),iv);
    }
}
